package heman.server.controllers;


import heman.common.XMLConverter;
import heman.server.entities.Player;
import heman.server.entities.Table;
import heman.server.entities.TableManager;

import java.util.ArrayList;

import ks.framework.common.Message;
import ks.framework.communicator.Communicator;
import ks.server.interfaces.IProcessServerMessage;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Chat controller handles CHAT messages.
 * 
 * <gameResponse table="13" turn="12995" move="(5/5)=L,(5/7)=E,(5/6)=I" from="113">
 * <gameState player="85" score="10"/>
 * <gameState player="113" score="10" game="numWins=5"/>
 * <gameState player="12995" score="0"/>
 * </gameResponse>
 * 
 * @author Wenlong Liu
 *
 */
public class GameResponseController implements IProcessServerMessage {

	public boolean process(Communicator com, Message m) {
		//This m is a turn message !!!
		String originator = m.getOriginator();
			
		StringBuilder sb= new StringBuilder(Message.responseHeader(true,m.id));
		
        //Get all the attributes of <turn> node
		Node root = m.contents();
        NamedNodeMap map=root.getAttributes();

        
        String tableID=map.
        		getNamedItem("table").getNodeValue();
        Table table=TableManager.getInstance().getTable(tableID);
        if (table==null) return false;
        
        //Get the move. Be careful that it is optional
        Node moveNode=map.
        		getNamedItem("move");
        Node completeNode=map.getNamedItem("complete");
        String move=null;
        if (moveNode!=null)
        	move=moveNode.getNodeValue();
        
        
        Player nextPlayer=table.getNextPlayer();
        if (nextPlayer==null)
        	//NO player on this table
        	return false;
        
        ArrayList<String> players=table.getAllPresentPlayerIDs();
        //Get the move
        
        sb.append("<gameResponse table=\"");
        sb.append(tableID);
        sb.append("\" turn=\"");
        
		//Send this gameResponse to the present player
		sb.append(nextPlayer.getId());
		
        sb.append("\"");
        
        if (move!=null){
        	//move==null means this is the start request
        	sb.append(" move=\"");
            sb.append(move+"\"");
            sb.append(" from=\"");
            sb.append(originator);
            sb.append("\"");
        }
        sb.append(">");
        
        //Get all game states
        NodeList children = root.getChildNodes();
        StringBuilder gssb=new StringBuilder();
        for (int i = 0; i < children.getLength(); i++) {
        	Node child = children.item(i);
        	gssb.append(XMLConverter.convertGameState(child));
        	
        }
        sb.append(gssb.toString());
        sb.append("</gameResponse></response>");
        //String string=sb.toString();
        Document d = Message.construct(sb.toString());
        Message r = new Message (d);
        r.setOriginator(originator);
        com.distribute(players.iterator(), r);
        
        if (completeNode==null || completeNode.getNodeValue().equals("true"))
        	//We are done. Don't have to generate the next turn.
        	return true;
        
		if (!table.onTable(nextPlayer)){
			//Generate a skip turn message
			StringBuilder s=new StringBuilder(Message.requestHeader());
			/**
			 * <turn table="99" skip="false" move="(5/5)=L,(5/7)=E,(5/6)=I" complete="false">
				  <gameState player="1284" score="35" game="special=value,client=only" /> 
				  <gameState player="335" score="135" game="special=value,client=only" /> 
				  </turn>
			 */
			s.append("<turn table=\""+tableID+"\" skip=\"true\" complete=\"false\">" +
					//Use the last game states
					gssb.toString()+
					"</turn></request>");
			Document dd = Message.construct(s.toString());
			
			Message tm=new Message(dd);
			tm.setOriginator(nextPlayer.getId());
			//Even though this should be done by a GameResponseController, ...
			new TurnController().process(com, tm);
			
		}
		return true;


	}

}
